<template>
  <div class="container">
    <el-row :gutter="20">
      <el-col :span="3">
        <el-button type="primary" @click="handleForm('common')"
          >添加通用配置</el-button
        >
        <br /><br />
        <el-button type="primary" @click="handleForm('form')"
          >添加配置项</el-button
        >
        <br /><br />
        <el-button type="primary" @click="handleBatchAddForm"
          >批量添加配置项</el-button
        >
        <br /><br />
        <el-button type="primary" @click="openReplaceProp"
          >替换prop字段</el-button
        >
      </el-col>
      <el-col :span="8" class="codeContainer">
        <pre
          class="code"
          ref="code"
          :contenteditable="isEditCode"
          @keyup="debounceEditCode"
          @keydown.stop=""
        ></pre>
        <el-button
          class="generateSourceCode btn"
          type="success"
          size="mini"
          @click="generateSourceCode"
          v-show="crudOpton.column.length"
          >格式化代码</el-button
        >
        <el-button
          class="generateCode btn"
          type="success"
          size="mini"
          @click="generateCode"
          v-show="crudOpton.column.length"
          >预览生成代码</el-button
        >
        <el-button
          class="clearCode btn"
          type="danger"
          size="mini"
          @click="clearCode"
          @dblclick="clear"
          v-show="crudOpton.column.length"
          >清空代码</el-button
        >
      </el-col>
      <el-col :span="13">
        <avue-crud
          v-if="crudOpton.column.length"
          ref="crud"
          :data="[{}, {}, {}, {}, {}]"
          :option="crudOpton"
        >
        </avue-crud>
      </el-col>
    </el-row>

    <el-dialog
      :visible.sync="visible"
      title="配置项"
      append-to-body
      width="60%"
      :before-close="dialogClose"
      top="8vh"
      :close-on-click-modal="false"
      custom-class="editDialog"
    >
      <avue-form ref="form" v-model="form" :option="option" @submit="submit">
        <template slot="menuForm">
          <el-button
            type="primary"
            icon="el-icon-document"
            size="small"
            @click="setFormDefault"
            >添加为默认值</el-button
          >
          <el-button
            type="primary"
            icon="el-icon-document"
            size="small"
            @click="removeFormDefault"
            >清除默认值</el-button
          >
        </template>
      </avue-form>
    </el-dialog>

    <el-dialog
      :visible.sync="codeVisible"
      title="代码查看"
      append-to-body
      width="60%"
      top="8vh"
      custom-class="sourceCodeContainer"
      @closed="nodePre = false"
      :close-on-click-modal="false"
    >
      <pre ref="sourceCode" class="sourceCode"></pre>
    </el-dialog>
  </div>
</template>

<script>
import {
  // @/util/util.js
  getRules,
  getDicOption,
  removeEmptyAttr,
  formatData,
  buildData,
  compose,
  formatNum,
  debounce,
  getValueByExp,
  CopyObj,
  getLocalStorage,
  setLocalStorage,
  removeLocalStorage,

  // @/options/verify.js
  handleVerify,
  numReg,
  handleVerifySelectData,
  whetherFieldList,

  // @/options/config.js
  typeFieldList,
  selectType,
  formDefault,
  commonDefault,
  propDefault,
  slotStr,
  nativeData,
  defaultSelectDataStr,
} from "@/util/index.js";

export default {
  name: "App",
  mounted() {
    window.addEventListener("keydown", (e) => {
      // e.preventDefault();
      if (e.keyCode === 220) {
        this.handleForm("form");
      }

      if (e.keyCode === 192 && this.isClearCode) {
        this.isClearCode = true;
        this.clearCode();
      }
      // console.log(e.keyCode);
    });
  },
  data() {
    return {
      // 防抖函数
      debounceEditCode: debounce(this.handleEditCode, 700),
      nodePre: false,
      visible: false,
      isClearCode: true,
      formNum: 0,
      codeVisible: false,
      isEditCode: true,
      code: "",
      form: {},
      option: {},
      formDefault,
      commonDefault,
      propDefault,
      // json配置数据
      formOption: {
        labelWidth: 100,
        submitText: "保存",
        tabs: true,
        group: [
          {
            label: "基本配置",
            arrow: false,
            column: [
              {
                label: "标签名",
                prop: "label",
                span: 8,
                tip: ">后缀文本, &或&&日期, ?系统字典, -文本域, =下拉是否 *必填",
                rules: getRules("请输入label名称"),
                change: ({ value }) => {
                  if (!value) return;
                  this.form.prop = "_" + value;
                },
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "属性名",
                prop: "prop",
                disabled: true,
                labelTip: "属性名(prop)不用填写, 可以快速进行替换",
                span: 8,
              },
              {
                label: "隐藏类型",
                prop: "hideType",
                span: 8,
                row: true,
                rules: getRules("请选择隐藏类型"),
                ...getDicOption(
                  [
                    ["表单隐藏", "form"],
                    ["列隐藏", "column"],
                    ["全部隐藏", "all"],
                  ],
                  "form"
                ),
              },
              {
                label: "开启搜索框",
                prop: "search",
                span: 8,
                change: ({ value }) => {
                  let flag = true;
                  if (value) {
                    flag = false;
                  }
                  const searchLabelTitleProp = "searchLabelTitle";
                  const searchSpanProp = "searchSpan";
                  const searchOrderProp = "searchOrder";
                  const searchLabelTitleObj =
                    this.getOptionObj(searchLabelTitleProp);
                  const searchSpanPropObj = this.getOptionObj(searchSpanProp);
                  const searchOrderObj = this.getOptionObj(searchOrderProp);
                  searchLabelTitleObj.disabled = flag;
                  this.form[searchLabelTitleProp] = this.form.label;
                  searchSpanPropObj.disabled = flag;
                  searchOrderObj.disabled = flag;
                },
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "搜索标签名",
                prop: "searchLabelTitle",
                span: 8,
                disabled: false,
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "搜索框宽度",
                prop: "searchSpan",
                span: 8,
                disabled: false,
                ...getDicOption(
                  [
                    ["6", "6"],
                    ["8", "8"],
                    ["12", "12"],
                    ["24", "24"],
                  ],
                  "6"
                ),
              },
              {
                label: "搜索框排序",
                prop: "searchOrder",
                span: 8,
                change: ({ value }) => {
                  if (!value) return;
                  handleVerify.call(this, value, "searchOrder");
                },
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "禁用",
                prop: "disabled",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "只读",
                prop: "readonly",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "系统字典",
                prop: "isDic",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "多选",
                prop: "multiple",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "默认值",
                prop: "value",
                span: 8,
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "前缀文本",
                prop: "prepend",
                span: 8,
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "后缀文本",
                prop: "append",
                span: 8,
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "前缀icon",
                prop: "prefixIcon",
                span: 8,
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "后缀icon",
                prop: "suffixIcon",
                span: 8,
                enter: () => {
                  this.$refs.form.submit();
                },
              },
            ],
          },
          {
            label: "表单配置",
            arrow: false,
            column: [
              {
                label: "表单类型",
                prop: "type",
                span: 8,
                rules: getRules("请输入表单类型"),
                ...getDicOption(typeFieldList, "input"),
                change: ({ value }) => {
                  const selectDataObj = this.getOptionObj("selectData");
                  if (selectType.includes(value) && !selectDataObj.disabled)
                    return;
                  let flag = true;
                  if (selectType.includes(value)) flag = false;
                  selectDataObj.disabled = flag;
                  this.form.selectData = "";
                },
              },
              {
                label: "表单项宽度",
                prop: "span",
                span: 8,
                rules: getRules("请选择表单项宽度"),
                ...getDicOption(
                  [
                    ["6", "6"],
                    ["8", "8"],
                    ["12", "12"],
                    ["24", "24"],
                  ],
                  "8"
                ),
              },
              {
                label: "单独成行",
                prop: "row",
                labelTip: "row 配置",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "单选/多选数据",
                prop: "selectData",
                // type: "search",
                append: "下拉默认数据",
                // suffixIcon: "el-icon-document-copy",
                row: true,
                span: 23,
                tip: "下拉默认数据格式: " + defaultSelectDataStr,
                tipPlacement: "top",
                labelWidth: 130,
                disabled: true,
                rules: [
                  {
                    trigger: "blur",
                    validator: (rule, value, callback) => {
                      try {
                        const dataArr = handleVerifySelectData(value);
                        let flag = true;

                        if (!Array.isArray(dataArr)) {
                          flag = false;
                        }

                        for (const item of dataArr) {
                          if (!Array.isArray(item) || item.length !== 2) {
                            flag = false;
                            break;
                          }
                        }

                        if (flag) {
                          callback();
                        } else {
                          callback(new Error("数据格式不对哦!"));
                        }
                      } catch (err) {
                        callback(new Error("数据格式不对哦!"));
                      }
                    },
                  },
                ],
                appendClick: () => {
                  this.copyCode(defaultSelectDataStr + "||", "复制成功");
                },
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "",
                prop: "nativeData",
                type: "textarea",
                span: 24,
                labelWidth: 0,
                row: true,
                showWordLimit: true,
                maxRows: 16,
                value: nativeData,
              },
            ],
          },
          {
            label: "表单验证",
            arrow: false,
            column: [
              {
                label: "表单验证",
                prop: "isRules",
                span: 6,
                change: ({ value }) => {
                  let flag = false;
                  if (!value) flag = true;
                  const obj = this.findObject(this.option.group, "rules");
                  obj.disabled = flag;
                  if (flag) {
                    this.form.rules = "";

                    const fieldList = ["rulesMax", "rulesMin"];
                    for (const item of fieldList) {
                      const obj = this.findObject(this.option.group, item);
                      obj.disabled = flag;
                      this.form[item] = "";
                    }
                  }
                },
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "验证方式",
                prop: "rules",
                span: 6,
                type: "select",
                disabled: true,
                ...getDicOption([
                  ["必填", "trigger"],
                  ["位数限制", "number"],
                ]),
                change: ({ value }) => {
                  if (!value) return;
                  let flag = false;
                  if (value !== "number") flag = true;
                  const fieldList = ["rulesMax", "rulesMin"];
                  for (const item of fieldList) {
                    const obj = this.findObject(this.option.group, item);
                    obj.disabled = flag;
                    if (flag) this.form[item] = "";
                  }
                },
              },
              {
                label: "最大位数",
                prop: "rulesMax",
                span: 6,
                disabled: true,
                change: ({ value }) => {
                  if (!val) return;
                  const val = value.replace(numReg, "");
                  const valArr = val.split("");
                  valArr.length = 2;
                  this.$nextTick(() => {
                    this.form.rulesMax = valArr.join("");
                  });
                },
                appendClick: () => {
                  this.copyCode(defaultSelectDataStr + "||", "复制成功");
                },
                enter: () => {
                  this.$refs.form.submit();
                },
              },
              {
                label: "最小位数",
                prop: "rulesMin",
                span: 6,
                disabled: true,
                change: ({ value }) => {
                  if (!val) return;
                  const val = value.replace(numReg, "");
                  const valArr = val.split("");
                  valArr.length = 2;
                  this.$nextTick(() => {
                    this.form.rulesMin = valArr.join("");
                  });
                },
                enter: () => {
                  this.$refs.form.submit();
                },
              },
            ],
          },
          {
            label: "插槽",
            arrow: false,
            column: [
              {
                label: "表单插槽",
                prop: "formslot",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "子表插槽",
                prop: "childrenTableslot",
                span: 8,
                readonly: true,
                click: () => {
                  this.copyCode(slotStr.childrenTableslot, "复制成功");
                },
              },
            ],
          },
        ],
      },
      // 通用配置
      commonOption: {
        labelWidth: 120,
        submitText: "保存",
        tabs: true,
        group: [
          {
            label: "基本配置",
            arrow: false,
            column: [
              {
                label: "表格边框",
                prop: "border",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "表格勾选列",
                prop: "selection",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "显示表格序号",
                prop: "index",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "显示索引",
                prop: "showIndex",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "显示表头",
                prop: "showHeade",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "显示斑马线",
                prop: "stripe",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "表格序号文案",
                prop: "indexLabel",
                span: 8,
              },
            ],
          },
          {
            label: "按钮权限",
            arrow: false,
            column: [
              {
                label: "添加按钮",
                prop: "addBtn",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "行编辑按钮",
                prop: "editBtn",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "行查看按钮",
                prop: "viewBtn",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "行删除按钮",
                prop: "delBtn",
                span: 8,
                ...getDicOption(whetherFieldList, false, "switch"),
              },
              {
                label: "表格刷新按钮",
                prop: "refreshBtn",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
              {
                label: "表格显隐按钮",
                prop: "columnBtn",
                span: 8,
                ...getDicOption(whetherFieldList, true, "switch"),
              },
            ],
          },
          {
            label: "排列配置",
            // collapse: false,
            arrow: false,
            column: [
              {
                label: "列的对其方式",
                prop: "align",
                span: 8,
                ...getDicOption([
                  ["居左", "left"],
                  ["居中", "center"],
                  ["居右", "right"],
                ]),
              },
              {
                label: "行菜单排列",
                prop: "menuAlign",
                span: 8,
                ...getDicOption([
                  ["居左", "left"],
                  ["居中", "center"],
                  ["居右", "right"],
                ]),
              },
              {
                label: "弹出按钮位置",
                prop: "dialogMenuPosition",
                span: 8,
                ...getDicOption([
                  ["居左", "left"],
                  ["居中", "center"],
                  ["居右", "right"],
                ]),
              },
            ],
          },
          {
            label: "宽度配置",
            // collapse: false,
            arrow: false,
            column: [
              {
                label: "搜索菜单宽度",
                prop: "searchMenuSpan",
                span: 8,
                ...getDicOption([
                  ["8", "8"],
                  ["24", "24"],
                ]),
              },
              {
                label: "搜索label宽度",
                prop: "searchLabelWidth",
                span: 8,
                change: ({ value }) => {
                  if (!value) return;
                  handleVerify.call(this, value, "searchLabelWidth");
                },
              },
              {
                label: "lebel名宽度",
                prop: "labelWidth",
                span: 8,
                change: ({ value }) => {
                  if (!value) return;
                  handleVerify.call(this, value, "labelWidth");
                },
              },
              {
                label: "列宽度",
                prop: "width",
                span: 8,
                change: ({ value }) => {
                  if (!value) return;
                  handleVerify.call(this, value, "width");
                },
              },
              {
                label: "列最小宽度",
                prop: "minWidth",
                span: 8,
                change: ({ value }) => {
                  if (!value) return;
                  handleVerify.call(this, value, "minWidth");
                },
              },
              {
                label: "操作菜单栏宽度",
                prop: "menuWidth",
                span: 8,
                change: ({ value }) => {
                  if (!value) return;
                  handleVerify.call(this, value, "menuWidth");
                },
              },
            ],
          },
          {
            label: "按钮文案",
            // collapse: false,
            arrow: false,
            column: [
              {
                label: "新增界面标题",
                prop: "addTitle",
                span: 8,
              },
              {
                label: "编辑界面标题",
                prop: "editTitle",
                span: 8,
              },
              {
                label: "查看界面标题",
                prop: "viewTitle",
                span: 8,
              },
              {
                label: "搜索按钮文案",
                prop: "searchBtnText",
                span: 8,
              },
              {
                label: "清空按钮文案",
                prop: "emptyBtnText",
                span: 8,
              },
              {
                label: "新增按钮文案",
                prop: "addBtnText",
                span: 8,
              },
              {
                label: "编辑按钮文案",
                prop: "editBtnText",
                span: 8,
              },
              {
                label: "查看按钮文案",
                prop: "viewBtnText",
                span: 8,
              },
              {
                label: "删除按钮文案",
                prop: "delBtnText",
                span: 8,
              },
              {
                label: "保存按钮文案",
                prop: "saveBtnText",
                span: 8,
              },
              {
                label: "取消按钮文案",
                prop: "cancelBtnText",
                span: 8,
              },
              {
                label: "数据为空文案",
                prop: "emptyText",
                span: 8,
              },
            ],
          },
          {
            label: "插槽相关",
            // collapse: false,
            arrow: false,
            column: [
              {
                label: "左上按钮插槽",
                prop: "menuLeft",
                tip: slotStr.menuLeft,
                span: 8,
                readonly: true,
                click: () => {
                  this.copyCode(slotStr.menuLeft, "复制成功");
                },
              },
              {
                label: "行内菜单插槽",
                prop: "menu",
                tip: slotStr.menu,
                span: 8,
                readonly: true,
                click: () => {
                  this.copyCode(slotStr.menu, "复制成功");
                },
              },
              {
                label: "弹窗菜单按钮",
                prop: "menuFormBtn",
                tip: slotStr.menuForm,
                span: 8,
                readonly: true,
                click: () => {
                  this.copyCode(slotStr.menuForm, "复制成功");
                },
              },
              {
                label: "搜素插槽",
                prop: "searchMenu",
                tip: slotStr.searchMenu,
                span: 8,
                readonly: true,
                click: () => {
                  this.copyCode(slotStr.searchMenu, "复制成功");
                },
              },
            ],
          },
        ],
      },
      // crud配置数据
      crudOpton: {
        column: [],
      },
      // 替换prop字段配置
      propOption: {
        labelWidth: 100,
        column: [
          {
            label: "URL地址",
            prop: "url",
            span: 24,
            labelTip: "doc.html 文档对应的接口地址(只支持 GET 请求类型)",
            tip: "示例: http://129.204.93.177:8069/blade-desk/v2/api-docs-ext",
            tipPlacement: "top",
            rules: getRules("请输入URL地址"),
          },
          {
            label: "属性字段",
            prop: "attributes",
            span: 24,
            labelTip: "用于解析 doc.html 文档返回的数据每个属性用 . 分割",
            tip: "示例: paths./notice/detail.get.parameters",
            // tip: "示例: paths.接口地址.接口类型.parameters",
            tipPlacement: "top",
            rules: getRules("请输入属性字段"),
          },
        ],
      },
    };
  },
  methods: {
    dialogClose() {
      this.visible = false;
      setTimeout(() => {
        this.option = {};
        this.$refs.form.resetForm();
      }, 300);
    },
    handleForm(flag) {
      this.visible = true;

      // 获取焦点
      if (this.$refs?.form) {
        this.$nextTick(() => {
          const labelObj = this.$refs.form.getPropRef("label");
          if (!labelObj) return;
          const input = labelObj.$el.querySelector("input");
          input.focus();
          setTimeout(() => {
            this.$refs.form.clearValidate();
            // 切换到第一个tabs
            this.$refs.form.activeName = "1";
            this.form.label = "";
            this.form.prop = "";
          }, 14);
        });
      }

      // this.$refs?.form?.resetForm();
      if (flag === "form") {
        this.option = this.formOption;
        this.defaultDataType = "formDefault";
        // 设置保存的默认值
        this.setDefaultForm("formDefault");
      }
      if (flag === "common") {
        this.option = this.commonOption;

        const crudOpton = CopyObj(this.crudOpton);
        delete crudOpton.column;
        this.defaultDataType = "commonDefault";
        // this.setDefaultForm("commonDefault");

        // 有设置公共属性时用公共属性
        if (Object.keys(crudOpton).length) {
          this.commonDefault = crudOpton;
        }
      }
      if (flag === "prop") {
        this.option = this.propOption;
        this.defaultDataType = "propDefault";
        this.setDefaultForm("propDefault");
      }
      // 默认值设置
      let options = CopyObj(this[this.defaultDataType]);
      for (const [key, value] of Object.entries(options)) {
        this.$set(this.form, key, value);
      }
    },
    submit(form, done) {
      let code = "";
      if (this.option === this.formOption) {
        // 组合去除空属性, 构建数据函数(自右向左)
        const buildDataFunc = compose(
          formatNum,
          compose(buildData, removeEmptyAttr)
        );
        code = buildDataFunc(form);
        this.crudOpton.column.push(code);
        // 批量添加
        if (this.formNum !== 0) {
          for (let i = 0; i < this.formNum - 1; i++) {
            this.crudOpton.column.push(code);
          }
          this.formNum = 0;
        }
        // this.copyCode(formatData(code, 2, true), "已复制当次配置代码");
      }

      if (this.option === this.commonOption) {
        const treeShakeFunc = compose(formatNum, removeEmptyAttr);
        code = treeShakeFunc(form);
        this.$nextTick(() => {
          for (const item of Object.keys(code)) {
            if (code[item] !== "") {
              this.$set(this.crudOpton, item, code[item]);
            }
          }
          this.copyCode(formatData(code, 2, true), "已复制当次配置代码");
        });
      }

      if (this.option === this.propOption) {
        const propOption = removeEmptyAttr(form);
        this.handleReplaceProp(CopyObj(propOption));
      }
      // console.log("当次配置", code);
      // console.log("curd配置", this.crudOpton);
      this.$nextTick(() => {
        this.generateSourceCode();
      });
      done();
      this.dialogClose();
    },
    getOptionObj(prop) {
      return this.findObject(this.option.group, prop);
    },
    generateSourceCode() {
      // if (this.isAction()) return;
      this.isEditCode = true;
      for (const item of this.crudOpton.column) {
        delete item.index;
      }
      const code = JSON.stringify(this.crudOpton, "*", 2);
      this.$refs.code.innerText = code;
    },
    generateCode() {
      // if (this.isAction()) return;
      this.codeVisible = true;
      this.$nextTick(() => {
        // const code = "option: " + formatData(this.crudOpton);
        const code = formatData(this.crudOpton.column, 2, true, true);
        this.$refs.sourceCode.innerText = code;
        this.copyCode(code, "已复制当次生成的代码");
      });
    },
    clearCode() {
      this.$confirm("此操作将删除代码, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.isClearCode = false;
          this.clear();
        })
        .catch(() => {});
    },
    clear() {
      this.isEditCode = false;
      this.$refs.code.innerText = "";
      this.$set(this, "crudOpton", {});
      this.$set(this.crudOpton, "column", []);
    },
    copyCode(text, message) {
      this.$Clipboard({
        text,
      })
        .then(() => {
          this.$message({
            message,
            type: "success",
            duration: 1500,
            offset: 80,
          });
        })
        .catch(() => {
          this.$message({
            message: "复制失败",
            type: "warning",
          });
        });
    },
    // pre元素编辑事件
    handleEditCode() {
      // 数据非法标识
      let flag = false;
      // 代码
      const code = this.$refs.code.innerText;
      try {
        // 判断数据是否合法
        JSON.parse(code);
      } catch (err) {
        console.log(err);
        // 不合法修改标识
        if (err) flag = true;
      } finally {
        // 数据合法才修改配置项
        if (!flag) {
          this.$nextTick(() => {
            this.$set(this, "crudOpton", JSON.parse(code));
            // this.generateSourceCode();
            // console.log("配置编辑数据", JSON.parse(code));
          });
        } else {
          this.$message({
            message: "数据不合法",
            type: "error",
            duration: 1300,
            offset: 80,
          });
        }
      }
    },
    handleBatchAddForm() {
      this.$prompt("请输入生成的数量", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputPattern: /^\d{1,2}$/,
        inputErrorMessage: "请输入数字(不超过两位数)",
      })
        .then(({ value }) => {
          this.formNum = value;
          this.handleForm("form");
        })
        .catch(() => {});
    },
    openReplaceProp() {
      if (this.isAction()) return;
      this.handleForm("prop");
    },
    async handleReplaceProp(propOption) {
      try {
        const { url, attributes } = propOption;
        const response = await fetch(url);
        // const response = await fetch(
        //   `https://112.74.107.43:5000/prop?url=${url.trim()}`
        // );
        if (!response.json) {
          this.$message({
            message: "请求失败",
            type: "error",
          });
          return;
        }
        const data = await response.json();
        // const resData = getValueByExp(JSON.parse(data), attributes.trim());
        const resData = getValueByExp(data, attributes.trim());
        // 替换字段
        for (const item of resData) {
          const { description, name } = item;
          for (const obj of this.crudOpton.column) {
            if (obj.label === description) {
              obj.prop = name;
            }
          }
        }
        // 生成代码
        this.generateSourceCode();
        const code = this.$refs.code.innerText;
        this.codeVisible = true;
        this.$nextTick(() => {
          this.$refs.sourceCode.innerText = code;
          this.copyCode(
            "option: " + formatData(this.crudOpton, 2),
            "已复制代码, 请检查字段是否替换正确"
          );
        });
      } catch (err) {
        this.$message({
          message: "替换失败, 错误信息请查看控制台",
          type: "error",
        });
        console.error(err);
      }
    },
    isAction(message) {
      message = message || "最少需要添加一个JSON配置项哦";
      if (!this.crudOpton.column.length) {
        this.$message({
          message,
          type: "warning",
        });
        return true;
      }
      return false;
    },
    // 保存默认值
    setFormDefault() {
      let defaultType = "",
        obj = CopyObj(this.form);

      switch (this.defaultDataType) {
        case "formDefault":
          obj.label = "";
          obj.prop = "";
          setLocalStorage("formDefault", obj);
          defaultType = "表单项";
          break;
        case "commonDefault":
          setLocalStorage("commonDefault", obj);
          defaultType = "公共配置";
          break;
        case "propDefault":
          setLocalStorage("propDefault", obj);
          defaultType = "prop 替换配置";
          break;
      }
      this.$message({
        message: `${defaultType}默认配置成功`,
        type: "success",
      });
    },
    // 设置保存的默认值
    setDefaultForm(key) {
      const defaultVal = getLocalStorage(key);
      defaultVal ? (this[key] = defaultVal) : undefined;
    },
    removeFormDefault() {
      let defaultType = "";
      switch (this.defaultDataType) {
        case "formDefault":
          defaultType = "表单项";
          this.formDefault = formDefault;
          break;
        case "commonDefault":
          defaultType = "公共配置";
          this.commonDefault = commonDefault;
          break;
        case "propDefault":
          defaultType = "prop 替换配置";
          this.propDefault = propDefault;
          break;
      }
      removeLocalStorage(this.defaultDataType);

      this.$message({
        message: `${defaultType}默认配置清除成功`,
        type: "success",
      });
    },
  },
};
</script>
<style lang="scss">
.container {
  padding: 20px 0;
  &:last-child {
    margin-bottom: 0;
  }
  .codeContainer {
    background: #f1f3f4;
    height: 50vh;
    overflow: auto;
    position: relative;
    .code {
      color: rgba(187, 42, 31, 0.774);
      font-weight: bolder;
      font-size: 14px;
      font-family: "Times New Roman", Georgia, serif;
      margin: 0;
    }
    .btn {
      position: fixed;
      top: 54vh;
    }
    button.generateSourceCode {
      left: 14vw;
    }
    button.generateCode {
      left: 24vw;
    }
    button.clearCode {
      left: 37vw;
    }
  }
}
.el-popup-parent--hidden {
  .el-dialog__wrapper {
    .el-dialog {
      .el-dialog__footer {
        padding: 0 !important;
      }
    }
    .editDialog {
      .el-dialog__body {
        padding: 4px !important;
      }
    }
  }
}

.copyText {
  color: white;
  font-size: 16px;
  font-weight: bold;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 4px;
  padding: 4px 8px;
  letter-spacing: 1px;
  opacity: 0;
  position: fixed;
  z-index: 9999;
  right: 0;
  bottom: 5%;
  transform: translate(-50%, -50%);
}
</style>